home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
MiscKit1.7.1
/
MiscKit
/
Source
/
MiscGISKit
/
MiscMathCoordConverter.m
< prev
next >
Wrap
Text File
|
1995-07-08
|
6KB
|
180 lines
/*======================= MiscMathCoordConverter.m ==========================*/
/* MiscMathCoordConverter class converts between various standard
Mathematical coordinate systems. All values are double precision floating
point numbers representing locations in a three dimensional coordinate
system.
There is only one instance ever, so unless changes are made, this class
is NON REENTRANT.
DMA Release 0.8, Copyright @1993 by Genesis Project, Ltd. All Rights
Reserved. For further information on terms and conditions see
the MiscKit license.
HISTORY
10-Mar-93 Dale Amon at GPL
Created.
*/
#import <ansi/math.h>
#import <misckit/miscgiskit.h>
@implementation MiscMathCoordConverter
/*===========================================================================*/
/* Internal methods
These are applied to each data point by a applyTransform:
*/
/*===========================================================================*/
/* Internal methods to convert a point to a different coordinate system.
Input vector is pointed to by src and the result of the transformation
is stored in dst.
*/
- (void) cartesianToCylindrical
{ dst[MISC_THETA_CYL] = atan(src[MISC_Y_COORD]/src[MISC_X_COORD]);
dst[MISC_RADIUS_CYL] = sqrt(src[MISC_X_COORD] * src[MISC_X_COORD] +
src[MISC_Y_COORD] * src[MISC_Y_COORD]);
dst[MISC_Z_CYL] = src[MISC_Z_COORD];
}
- (void) sphericalToCylindrical
{ dst[MISC_THETA_CYL] = src[MISC_THETA_SPHERE];
dst[MISC_RADIUS_CYL] = src[MISC_RHO_SPHERE] * sin(src[MISC_PHI_SPHERE]);
dst[MISC_Z_CYL] = src[MISC_RHO_SPHERE] * cos(src[MISC_PHI_SPHERE]);
}
- (void) cartesianToSpherical
{ double xsq,ysq;
xsq = src[MISC_X_COORD] * src[MISC_X_COORD];
ysq = src[MISC_Y_COORD] * src[MISC_Y_COORD];
dst[MISC_RHO_SPHERE] = sqrt(xsq + ysq +
src[MISC_Z_COORD] * src[MISC_Z_COORD]);
dst[MISC_THETA_SPHERE] = atan(src[MISC_Y_COORD]/src[MISC_X_COORD]);
dst[MISC_PHI_SPHERE] = atan(sqrt(xsq + ysq)/src[MISC_Z_COORD]);
}
- (void) cylindricalToSpherical
{ dst[MISC_RHO_SPHERE] = sqrt(src[MISC_RADIUS_CYL] * src[MISC_RADIUS_CYL] +
src[MISC_Z_CYL] * src[MISC_Z_CYL]);
dst[MISC_THETA_SPHERE] = src[MISC_THETA_CYL];
dst[MISC_PHI_SPHERE] = atan(src[MISC_RADIUS_CYL]/src[MISC_Z_CYL]);
}
- (void) cylindricalToCartesian
{ dst[MISC_X_COORD] = src[MISC_RADIUS_CYL] * cos(src[MISC_THETA_CYL]);
dst[MISC_Y_COORD] = src[MISC_RADIUS_CYL] * sin(src[MISC_THETA_CYL]);
dst[MISC_Z_COORD] = src[MISC_Z_CYL];
}
- (void) sphericalToCartesian
{ dst[MISC_X_COORD] = src[MISC_RHO_SPHERE] * sin(src[MISC_PHI_SPHERE]) *
cos(src[MISC_THETA_CYL]);
dst[MISC_Y_COORD] = src[MISC_RHO_SPHERE] * sin(src[MISC_PHI_SPHERE]) *
sin(src[MISC_THETA_CYL]);
dst[MISC_Z_COORD] = src[MISC_RHO_SPHERE] * cos(src[MISC_PHI_SPHERE]);
}
/*===========================================================================*/
/* Class methods */
/*===========================================================================*/
/* Only one converter of this type is every needed. Of course if we got
into a really big multiprocess agora system there might be a case
for multiple converters. Since this object is shared by many, it
doesn't particularly matter what zone it is allocated from.
*/
static id theMathCoordConverter = nil;
+ new
{
if (!theMathCoordConverter) theMathCoordConverter = [[super alloc] init];
return theMathCoordConverter;
}
/*---------------------------------------------------------------------------*/
/* Since there is only one object needed, alloc and allocFromZone: are
disabled and considered errors. free is simply overridden and made into a
no op.
*/
+alloc
{ [self error:" %s class should not be sent '%s' messages\n",
[[self class] name], sel_getName(_cmd)];
return self;
}
+allocFromZone: (NXZone *)zone
{ [self error:" %s class should not be sent '%s' messages\n",
[[self class] name], sel_getName(_cmd)];
return self;
}
- free {return self;}
/*===========================================================================*/
/* Initialization methods */
/*===========================================================================*/
/* We add a list of all the services which we are able to provide.
Note that there is only one PlanetCoordConverter ever created. Once
initialized the same object is given to all comers and can not be destroyed.
*/
- init
{ Class sphere,cylinder,cartesian;
[super init];
sphere = [MiscSphericalCoord class];
cylinder = [MiscCylindricalCoord class];
cartesian = [MiscCartesianCoord class];
[self addService: @selector(cartesianToCylindrical)
convertsFrom: cartesian to: cylinder];
[self addService: @selector(sphericalToCylindrical)
convertsFrom: sphere to: cylinder];
[self addService: @selector(cartesianToSpherical)
convertsFrom: cartesian to: sphere];
[self addService: @selector(cylindricalToSpherical)
convertsFrom: cylinder to: sphere];
[self addService: @selector(cylindricalToCartesian)
convertsFrom: cylinder to: cartesian];
[self addService: @selector(sphericalToCartesian)
convertsFrom: sphere to: cartesian];
[self addService: [self fastCopySelector]
convertsFrom: sphere to: sphere];
[self addService: [self fastCopySelector]
convertsFrom: cylinder to: cylinder];
[self addService: [self fastCopySelector]
convertsFrom: cartesian to: cartesian];
return self;
}
/*===========================================================================*/
/* Archive methods */
/*===========================================================================*/
- finishUnarchiving
{
[self free];
return [MiscMathCoordConverter new];
}
@end